﻿package datastore
         
import (  
    //"io"
    "bufio"
    //"io/ioutil"
    "fmt"
    "os"
    "bytes"
    "time"    
    "encoding/binary"
    //"unicode/utf8"
    "code.google.com/p/mahonia"
)  
  
type DicFileHeader struct {  
}
/*
  PStore_DealItem32     = ^TStore_DealItem32;
  TStore_DealItem32     = packed record // 128
    Code                : array[0..12 - 1] of AnsiChar; // 12
    Name                : array[0..6 - 1] of WideChar; // 12
    Country             : Word; // 2 26
    FirstDealDate       : Word; // 2 28
    EndDate             : Word; // 2 30
  end;

  PStore_DealItem32Rec  = ^TStore_DealItem32Rec;
  TStore_DealItem32Rec  = packed record
    ItemRecord          : TStore_DealItem32;
    Reserve             : array[0..32 - 1 - SizeOf(TStore_DealItem32)] of Byte;
  end;
*/

/*
1.字节切片基本处理函数api

1.1Contains()函数

//Contains()函数的功能是检查字节切片b是否包含子切片subslice,如果包含返回true,否则返回false.
1.2Count()函数

//Count()函数的功能是计算字节切片sep在字节切片s中非重叠显示的个数.
func Count(s,sep[]byte) int
1.3Repeat()函数

//Repeat()函数的功能是把切片b复制count个,然后合成一个新的字节切片返回.
func Repeat(b[]byte,count int) []byte
1.4Replace()函数

//Replace()函数的功能是返回字节切片s的一个副本,并把前n个不重叠的
//子切片old替换为new;如果n<0,则不限制替换的数量.参数n为替换的次数
func Replace(s,old,new []byte,n int) []byte
1.5Runes()函数

//Runes()函数的功能是把s转换为UTF-8编码的字节序列,并返回对应的Unicode切片.
func Runes(s []byte) []rune
1.6Join()函数

Join函数的功能是用字节切片sep把s中的每个字节切片连成一个字节切片并返回.
func Join(s [][]byte,sep[]byte) []byte
*/
type DicHead struct {
    Signature        uint16                 
    DataVer1         byte
    DataVer2         byte
    DataVer3         byte
    BytesOrder       byte
    HeadSize         byte             // 1 -- 7
    StoreSizeMode    byte  // 1 -- 8 page size mode
    DataType         uint16             // 2 -- 10
    DataMode         byte             // 1 -- 11
    RecordSizeMode   byte  // 1 -- 12
    RecordCount      int32          // 4 -- 16
    CompressFlag     byte             // 1 -- 17
    EncryptFlag      byte             // 1 -- 18
    DataSourceId     uint16             // 2 -- 20
}

func NewHead(buf []byte)*DicHead{
    head := new(DicHead) 
    //head.Signature      = binary.BigEndian.Uint16(buf[0:2])
    head.Signature      = binary.LittleEndian.Uint16(buf[0:2])
    head.HeadSize       = buf[6]
    head.StoreSizeMode  = buf[7]
    head.DataType       = binary.LittleEndian.Uint16(buf[8:10])
    head.DataMode       = buf[10]
    head.RecordSizeMode = buf[11]

    byte_buf := bytes.NewBuffer(buf[12:16])
    binary.Read(byte_buf, binary.LittleEndian, &head.RecordCount)
    
    //binary.Write(buf[8:12], binary.BigEndian, head.RecordCount)
    //binary.Read(buf[8:12], binary.BigEndian, &head.RecordCount)

    head.CompressFlag   = buf[16]
    head.EncryptFlag    = buf[17]
    head.DataSourceId   = binary.LittleEndian.Uint16(buf[18:20])
    return head
}
     
var (
  dicfileurl = "E:\\StockApp\\sdata\\s_dic\\items.dic"
)
                                            
//  DelphiDateDelta = 693594;
/*
func delphiDate2Date(delphiDate uint16) uint16 {
    return delphiDate;
}
//*/
//*                   
//  UnixDateDelta = 25569;
func delphiDate2Date_i16(delphiDate uint16) string {
    var unixdatetime int64 = int64(delphiDate);
    unixdatetime = unixdatetime - 25569;
    unixdatetime = unixdatetime * 60 * 60 * 24;
    str_time := time.Unix(unixdatetime, 0).Format("2006-01-02 15:04:05")
    //str_time := time.Unix(1389058332, 0).Format("2006-01-02 15:04:05")
    return str_time;
} 
//*/

func LoadDictionaryDataFromFile() {
    // f, err := os.OpenFile("test.txt", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm|os.ModeTemporary)
    f, err := os.Open(dicfileurl)//打开文件
    defer f.Close() //打开文件出错处理
    if nil == err {
        filereader := bufio.NewReader(f) //读入缓存
        rowindex := 0;
        buff_header := make([]byte, 64)
        filereader.Read(buff_header)

        head := NewHead(buff_header)
        fmt.Printf("Signature: %d\n", head.Signature)    
        fmt.Printf("HeadSize: %d\n", head.HeadSize)
        fmt.Printf("StoreSizeMode: %d\n", head.StoreSizeMode)
        fmt.Printf("DataType: %d\n", head.DataType)          
        fmt.Printf("DataMode: %d\n", head.DataMode)
        fmt.Printf("RecordSizeMode: %d\n", head.RecordSizeMode)
        fmt.Printf("recordcount: %d\n", head.RecordCount)      
        fmt.Printf("CompressFlag: %d\n", head.CompressFlag)    
        fmt.Printf("EncryptFlag: %d\n", head.EncryptFlag)
        fmt.Printf("DataSourceId: %d\n", head.DataSourceId)
        
        buff_code := make([]byte, 12)

        // utf8.RuneCountInString(buff_name)
        // http://blog.csdn.net/mchenys/article/details/51044589
        buff_name := make([]byte, 12)

        buff := make([]byte, 8)
        utf_encoder := mahonia.NewEncoder("UTF-16")

        for {
            filereader.Read(buff_code)
            filereader.Read(buff_name)
            readsize, _ := filereader.Read(buff)
            if 0 < readsize {
                rowindex++
                //fmt.Printf("line%d %d\n", rowindex, readsize)
                //name := bytes.Runes(buff_name)
                //name := utf8.RuneCountInString(name)
                //widestr := utf8encoder.ConvertString(string(buff_name))
                //widestr := utf_encoder.ConvertString(string(name))
                widestr := utf_encoder.ConvertString(string(buff_name))
                fmt.Printf("line%d %d %s %s\n", rowindex, readsize, string(buff_code), string(widestr))

                country := binary.LittleEndian.Uint16(buff[0:2])
                //firstDealDate := binary.LittleEndian.Uint16(buff[2:4])
                firstDealDate := delphiDate2Date_i16(binary.LittleEndian.Uint16(buff[2:4]));
                endDate := binary.LittleEndian.Uint16(buff[4:6])
                fmt.Printf("%d %s %d\n", country, firstDealDate, endDate)
                if 10 < rowindex {
                    break
                }
            } else {
                fmt.Printf("end!")
                break
            }
        }
    }
}  
